import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/widgets/gesture/kq_gesture_detector.dart';

import '../../../resources/l10n/kq_core_s.dart';

abstract class BaseChartDelegate<D> {
  BaseChartDelegate(
      {this.animDuration,
      this.data,
      this.gestureHandler,
      this.emptyWidgetBuilder,
      this.isDataEmpty});

  /// 动画时间，设置此值则启用动画绘制
  final Duration? animDuration;

  final D? data;

  final bool Function(D? data)? isDataEmpty;

  /// 当[isEmptyData]返回true时显示的内容
  final Widget Function()? emptyWidgetBuilder;

  final BaseChartGestureHandlerMixin? gestureHandler;

  ChartStateMixin? _chartState;

  /// 此代理关联的[State]
  ChartStateMixin? get chartState => _chartState;

  Size _size = Size.zero;

  /// 图表组件占用大小
  Size get size => _size;

  bool get isEmptyData;

  void onDraw(Canvas canvas, double animProgress);

  /// 关联上Chart，此时[State.initState]已执行
  @mustCallSuper
  void attachChart(ChartStateMixin state) {
    _chartState = state;
    gestureHandler?.attachChart(this);
  }

  @mustCallSuper
  void didUpdateWidget(covariant BaseChart oldWidget) {}

  /// 界面销毁
  @mustCallSuper
  void dispose() {
    _chartState = null;
    gestureHandler?.dispose();
  }

  /// 刷新界面数据
  void update() {
    _chartState?.update();
  }
}

class _ChartGestureHandlerWrapper<C extends BaseChartDelegate> {
  BaseChartDelegate? _delegate;
  DragDownDetails? _dragDownDetails;
  bool _isMove = false;

  void attachChart(C delegate) {
    _delegate?.gestureHandler?.attachChart(delegate);
  }

  void dispose() {
    _delegate?.gestureHandler?.dispose();
  }

  void onTapDown(DragDownDetails details) {
    _isMove = false;
    var padding = _delegate?.chartState?.widget.padding;
    if (padding == null) {
      _dragDownDetails = details;
      _delegate?.gestureHandler?.onTapDown(details);
    } else {
      var wrapperDetails = DragDownDetails(
          globalPosition: details.globalPosition,
          localPosition: details.localPosition == details.globalPosition
              ? details.localPosition
              : details.localPosition.translate(-padding.left, -padding.top));
      _dragDownDetails = wrapperDetails;
      _delegate?.gestureHandler?.onTapDown(wrapperDetails);
    }
  }

  void onTapUp() {
    _delegate?.gestureHandler?.onTapUp(_dragDownDetails ?? DragDownDetails());
  }

  void onDragEnd(DragEndDetails details) {
    if (!_isMove) {
      onTapUp();
      return;
    }

    _delegate?.gestureHandler?.onDragEnd(details);
  }

  void onDragStart(DragStartDetails details) {
    var padding = _delegate?.chartState?.widget.padding;
    if (padding == null) {
      _delegate?.gestureHandler?.onDragStart(details);
    } else {
      var wrapperDetails = DragStartDetails(
          sourceTimeStamp: details.sourceTimeStamp,
          globalPosition: details.globalPosition,
          localPosition: details.localPosition == details.globalPosition
              ? details.localPosition
              : details.localPosition.translate(-padding.left, -padding.top));
      _delegate?.gestureHandler?.onDragStart(wrapperDetails);
    }
  }

  void onDragUpdate(DragUpdateDetails details) {
    if (details.delta.distanceSquared <= 0) {
      return;
    }

    _isMove = true;
    var padding = _delegate?.chartState?.widget.padding;
    if (padding == null) {
      _delegate?.gestureHandler?.onDragUpdate(details);
    } else {
      var wrapperDetails = DragUpdateDetails(
          sourceTimeStamp: details.sourceTimeStamp,
          delta: details.delta,
          primaryDelta: details.primaryDelta,
          globalPosition: details.globalPosition,
          localPosition: details.localPosition == details.globalPosition
              ? details.localPosition
              : details.localPosition.translate(-padding.left, -padding.top));
      _delegate?.gestureHandler?.onDragUpdate(wrapperDetails);
    }
  }
}

/// 手势事件处理
mixin BaseChartGestureHandlerMixin<C extends BaseChartDelegate> {
  /// 是否可点击
  bool get tapEnable;

  /// 是否可滑动、拖拽,旋转等发生位移的手势
  bool get dragEnable;

  void attachChart(C delegate);

  void dispose();

  /// 手指按下，此事件发生在手指首次触摸屏幕
  void onTapDown(DragDownDetails details);

  /// 手指抬起，此事件发生在手指首次触摸屏幕后未发生滑动后抬起
  void onTapUp(DragDownDetails details);

  /// 拖拽开始，此事件发生在手指按下首次滑动
  void onDragStart(DragStartDetails details);

  /// 拖拽更新，此事件发生在手指持续滑动过程
  void onDragUpdate(DragUpdateDetails details);

  /// 拖拽结束，此事件发生在手指持续滑动后抬起
  void onDragEnd(DragEndDetails details);
}

/// 图表
class BaseChart extends StatefulWidget {
  const BaseChart({super.key, this.padding, required this.delegate});

  final BaseChartDelegate delegate;
  final EdgeInsets? padding;

  @override
  State<StatefulWidget> createState() => KqChartState();
}

/// 图表关联的[State]对外暴露内容
mixin ChartStateMixin {
  /// 更新数据
  update();

  /// 获取state关联的Widget
  BaseChart get widget;

  /// 用于创建动画
  TickerProvider get vsync;
}

/// 科强表格[State]基类
class KqChartState extends State<BaseChart>
    with TickerProviderStateMixin, ChartStateMixin {
  /// 控制绘制动画
  AnimationController? _animationController;
  final _ChartGestureHandlerWrapper _gestureHandlerWrapper =
      _ChartGestureHandlerWrapper();
  Duration? _animDuration;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(vsync: this);
    _animDuration = widget.delegate.animDuration;
    _gestureHandlerWrapper._delegate = widget.delegate;
    widget.delegate.attachChart(this);
  }

  @override
  void dispose() {
    _animationController?.dispose();
    widget.delegate.dispose();
    super.dispose();
  }

  @override
  void didUpdateWidget(covariant BaseChart oldWidget) {
    super.didUpdateWidget(oldWidget);
    _animDuration = widget.delegate.animDuration;
    widget.delegate.attachChart(this);
    _gestureHandlerWrapper._delegate = widget.delegate;
    widget.delegate.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    _animationController?.stop(canceled: true);
    var builder = widget.delegate.emptyWidgetBuilder;
    if (widget.delegate.isEmptyData && builder != null) {
      return _mapChild(builder.call());
    }

    var gestureHandler = widget.delegate.gestureHandler;
    if (gestureHandler == null ||
        (!gestureHandler.tapEnable && !gestureHandler.dragEnable)) {
      return _mapChild(SizedBox.expand(child: _buildContent(context)));
    }

    if (gestureHandler.tapEnable && !gestureHandler.dragEnable) {
      return GestureDetector(
        onTapDown: (details) {
          _gestureHandlerWrapper.onTapDown(DragDownDetails(
              globalPosition: details.globalPosition,
              localPosition: details.localPosition));
        },
        onTapUp: (details) {
          _gestureHandlerWrapper.onTapUp();
        },
        child: _mapChild(SizedBox.expand(child: _buildContent(context))),
      );
    } else {
      // 当前图表如果被包裹在滑动组件中，如果未触发滑动且手指抬起，则直接触发onDragCancel。
      // 当前图表如果未包裹在滑动列表中，如果未触发滑动且手指抬起，则触发onDragEnd。
      return KqGestureDetector(
        onDragDown: _gestureHandlerWrapper.onTapDown,
        onDragStart: gestureHandler.dragEnable
            ? _gestureHandlerWrapper.onDragStart
            : null,
        onDragUpdate: gestureHandler.dragEnable
            ? _gestureHandlerWrapper.onDragUpdate
            : null,
        onDragEnd:
            gestureHandler.dragEnable ? _gestureHandlerWrapper.onDragEnd : null,
        onDragCancel:
            gestureHandler.tapEnable ? _gestureHandlerWrapper.onTapUp : null,
        child: _mapChild(SizedBox.expand(child: _buildContent(context))),
      );
    }
  }

  Widget _mapChild(Widget child) {
    if (widget.padding != null) {
      return Padding(padding: widget.padding!, child: child);
    }
    return child;
  }

  Widget _buildContent(BuildContext context) {
    return _animDuration == null || widget.delegate.isEmptyData
        ? buildChild(context, 1)
        : _withAnim(_animDuration!);
  }

  Widget _withAnim(Duration duration) {
    _animationController?.duration = duration;
    var widget = AnimatedBuilder(
      animation: _animationController!,
      builder: (context, child) {
        return buildChild(context, _animationController?.value ?? 1);
      },
    );
    _animationController?.forward(from: 0);
    return widget;
  }

  @protected
  Widget buildChild(BuildContext context, double animProgress) {
    return CustomPaint(
        painter: _ChartPainter(state: this, animProgress: animProgress));
  }

  @override
  void update() {
    setState(() {
      _animDuration = null;
    });
  }

  @override
  TickerProvider get vsync => this;
}

/// 图表绘制器
class _ChartPainter extends CustomPainter {
  const _ChartPainter({required this.state, this.animProgress = 1})
      : assert(animProgress >= 0 && animProgress <= 1);

  /// 绘制器所依赖的饼状图[KqBasePieChartState]
  final KqChartState state;

  /// 动画进度，用于根据动画进行进行绘制
  final double animProgress;

  @override
  void paint(Canvas canvas, Size size) {
    state.widget.delegate._size = size;
    if (size.isEmpty) {
      return;
    }

    state.widget.delegate.onDraw(canvas, animProgress);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

/// 获取默认的空数据界面
Widget getDefEmptyView({double fontSize = 12, Color color = Colors.black}) =>
    Align(
      alignment: Alignment.center,
      child: Text(
        KqCoreS.currentResource.noDataTip,
        style: TextStyle(fontSize: fontSize, color: color),
      ),
    );
